<template>
  <div class="document-uploader">
    <a-card title="上传作业文档" :bordered="false">
      <template #extra>
        <a-tag color="processing" v-if="fileInfo.url">已上传</a-tag>
      </template>
      
      <a-upload-dragger
        v-model:fileList="fileList"
        name="file"
        :multiple="false"
        :before-upload="beforeUpload"
        :showUploadList="false"
        @change="handleUploadChange"
        :customRequest="customRequest"
      >
        <div v-if="!fileInfo.url && !uploading">
          <p class="ant-upload-drag-icon">
            <inbox-outlined />
          </p>
          <p class="ant-upload-text">点击或拖拽文件到此区域上传作业文档</p>
          <p class="ant-upload-hint">
            支持单个文件上传，如Word、PDF等格式。
          </p>
        </div>
        <div v-else-if="uploading">
          <p class="ant-upload-drag-icon">
            <loading-outlined spin />
          </p>
          <p class="ant-upload-text">正在上传文档</p>
          <a-progress :percent="uploadProgress" status="active" />
        </div>
        <div v-else>
          <p class="ant-upload-drag-icon">
            <file-outlined :style="{ color: '#52c41a' }" />
          </p>
          <p class="ant-upload-text">{{ fileInfo.filename || '文档已上传' }}</p>
          <p class="ant-upload-hint">
            <a-button size="small" type="text" @click.stop="resetUpload">
              <template #icon><delete-outlined /></template>
              删除文档
            </a-button>
            <a-button size="small" type="link" @click.stop="downloadFile">
              <template #icon><download-outlined /></template>
              下载文档
            </a-button>
          </p>
        </div>
      </a-upload-dragger>
    </a-card>
  </div>
</template>

<script lang="ts">
import { ref, reactive, defineComponent, watch } from 'vue'
import { message } from 'ant-design-vue'
import { 
  InboxOutlined, 
  FileOutlined, 
  DeleteOutlined, 
  DownloadOutlined,
  LoadingOutlined
} from '@ant-design/icons-vue'
import { uploadFile } from '@/api/assignment'
import type { UploadChangeParam } from 'ant-design-vue'
import { saveAs } from 'file-saver'

export default defineComponent({
  name: 'DocumentUploader',
  components: {
    InboxOutlined,
    FileOutlined,
    DeleteOutlined,
    DownloadOutlined,
    LoadingOutlined
  },
  props: {
    initialFileUrl: {
      type: String,
      default: ''
    },
    initialFilename: {
      type: String,
      default: ''
    }
  },
  emits: ['update:fileUrl', 'update:fileData'],
  setup(props, { emit }) {
    const fileList = ref<any[]>([])
    const uploading = ref(false)
    const uploadProgress = ref(0)
    
    // 文件信息
    const fileInfo = reactive({
      url: props.initialFileUrl || '',
      filename: props.initialFilename || ''
    })
    
    // 监听props变化
    watch(() => props.initialFileUrl, (newUrl) => {
      if (newUrl && newUrl !== fileInfo.url) {
        fileInfo.url = newUrl
      }
    })
    
    watch(() => props.initialFilename, (newName) => {
      if (newName && newName !== fileInfo.filename) {
        fileInfo.filename = newName
      }
    })
    
    // 上传前检查
    const beforeUpload = (file: File) => {
      // 检查文件类型
      const isAccepted = [
        'application/msword', 
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/pdf',
        'text/plain'
      ].includes(file.type)
      
      if (!isAccepted) {
        message.error('请上传Word、PDF或文本文档')
        return false
      }
      
      // 检查文件大小 (10MB限制)
      const isLt10M = file.size / 1024 / 1024 < 10
      if (!isLt10M) {
        message.error('文件大小不能超过10MB!')
        return false
      }
      
      return true
    }
    
    // 自定义上传请求
    const customRequest = async (options: any) => {
      const { file, onSuccess, onError } = options
      
      try {
        uploading.value = true
        
        // 模拟上传进度
        const progressInterval = setInterval(() => {
          if (uploadProgress.value < 95) {
            uploadProgress.value += 5
          }
        }, 200)
        
        // 调用上传API
        const res = await uploadFile(file)
        clearInterval(progressInterval)
        
        if (res.code === 200 && res.data) {
          uploadProgress.value = 100
          // 处理后端返回的数据格式，res.data可能直接是文件URL字符串
          const fileUrl = typeof res.data === 'string' ? res.data : res.data.url
          fileInfo.url = fileUrl
          fileInfo.filename = file.name
          
          emit('update:fileUrl', fileUrl)
          emit('update:fileData', {
            url: fileUrl,
            filename: fileInfo.filename
          })
          
          onSuccess(res, file)
          message.success('文档上传成功')
        } else {
          onError(new Error(res.message || '上传失败'))
          message.error(res.message || '上传失败')
        }
      } catch (error) {
        onError(error)
        console.error('上传文档失败:', error)
        message.error('上传文档失败')
      } finally {
        uploading.value = false
      }
    }
    
    // 处理上传状态变化
    const handleUploadChange = (info: UploadChangeParam) => {
      if (info.file.status === 'done') {
        fileList.value = [info.file]
      } else if (info.file.status === 'error') {
        fileList.value = []
      }
    }
    
    // 重置上传
    const resetUpload = () => {
      fileInfo.url = ''
      fileInfo.filename = ''
      fileList.value = []
      uploadProgress.value = 0
      
      emit('update:fileUrl', '')
      emit('update:fileData', { url: '', filename: '' })
    }
    
    // 下载文件
    const downloadFile = () => {
      if (fileInfo.url) {
        // 使用file-saver库处理文件下载
        fetch(fileInfo.url)
          .then(res => res.blob())
          .then(blob => {
            saveAs(blob, fileInfo.filename || 'document')
          })
          .catch(err => {
            console.error('下载文件失败:', err)
            message.error('下载文件失败')
          })
      }
    }
    
    return {
      fileList,
      uploading,
      uploadProgress,
      fileInfo,
      beforeUpload,
      customRequest,
      handleUploadChange,
      resetUpload,
      downloadFile
    }
  }
})
</script>

<style scoped>
.document-uploader {
  margin-bottom: 20px;
}

.parse-actions {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

.parsing-status {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  padding: 20px 0;
}

.parse-result {
  margin-top: 16px;
}

.content-preview {
  margin-top: 16px;
}

.content-text {
  white-space: pre-wrap;
  background-color: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  max-height: 200px;
  overflow-y: auto;
  font-size: 14px;
  line-height: 1.5;
}
</style> 